import { ref } from 'vue'
import router from '@/router'
import { defineStore } from 'pinia'
import { useRoute } from 'vue-router'
import { staticRoutes, lastRouters } from '@/router/modules'
import { normalizeRoutes, transformMenuToRoutes } from '@/router/transform'
import { formLogin } from '@/api/oauth2/OAuth.ts'
import type { UserInfo } from '@/api/types/UserTypes'
import type { OAuth2TokenResult } from '@/api/types/OAuth2Types'
import { loginUserinfo } from '@/api/system/User.ts'
import { getAsyncRoutes } from '@/api/system/Permission.ts'
import { authorizationLogout } from '@/api/platform/Authorization.ts'

const logo = new URL(`../assets/logo.png`, import.meta.url).href

export const useUserStore = defineStore(
	'User',
	() => {
		// 头像
		const picture = ref(logo)

		// 昵称
		const nickname = ref('')

		// 用户完整信息
		const userinfo = ref<UserInfo>()

		// 拥有的菜单
		const routers = ref()

		const route = useRoute()

		const oauth2Token = ref<OAuth2TokenResult>()

		// 路由是否被初始化
		const isRouterInitialized = ref(false)

		// 设置用户基础信息
		function setupUser(user: UserInfo) {
			userinfo.value = user
			if (user.picture) {
				picture.value = user.picture
			}
			nickname.value = user.nickname
		}

		async function getRouters() {
			if (routers.value && routers.value.length > 0) {
				// 将子路由的绝对路径转为相对路径
				return normalizeRoutes([...staticRoutes, ...routers.value])
			}

			try {
				const routerList = await getAsyncRoutes()
				if (routerList) {
					routers.value = routerList
					return [...staticRoutes, ...routers.value]
				}
			} catch (error: any) {
				if (error.response?.status === 401) {
					router.push({ path: '/login' }).then(reset)
				}
				console.error(error)
			}

			return staticRoutes
		}

		// 初始化Router
		async function initRouter() {
			// 初始化过跳出
			if (isRouterInitialized.value) {
				return
			}

			if (!routers.value || routers.value.length === 0) {
				try {
					const routerList = await getAsyncRoutes()
					if (routerList) {
						routers.value = routerList
					}
				} catch (error: any) {
					if (error.response?.status === 401) {
						router.push({ path: '/login' }).then(reset)
					}
					console.log(error)
					return
				}
			}

			if (!routers.value || routers.value.length === 0) {
				isRouterInitialized.value = true
				// 添加最后的路由(404)
				lastRouters.forEach((route) => router.addRoute(route))
				return
			}

			// 将组件从字符串转为实际的Vue组件
			const dynamicRoutes = transformMenuToRoutes(routers.value, true)
			// 将子路由的绝对路径转为相对路径
			const normalizedRoutes = normalizeRoutes(dynamicRoutes)

			// 添加路由
			normalizedRoutes.forEach((route: any) => {
				router.addRoute(route)
			})

			// 添加最后的路由(404)
			lastRouters.forEach((route) => router.addRoute(route))

			isRouterInitialized.value = true
		}

		// 登录
		function login(type: string, data: any) {
			return new Promise((resolve, reject) => {
				switch (type) {
					case 'account':
					case 'email':
					case 'qr-code':
						const oauth2Login = !!route.query.target
						formLogin(data, oauth2Login, type)
							.then((res) => {
								if (oauth2Login) {
									window.location.href = route.query.target as string
									resolve(true)
									return
								}
								if (res.expires_in && res.expires_in > 0) {
									// 过期时长转为具体的过期时间
									res.expires_in = Date.now() + res.expires_in * 1000
								}
								oauth2Token.value = res
								loginUserinfo()
									.then((userResult) => {
										setupUser(userResult)
										resolve(true)
									})
									.catch(reject)
							})
							.catch(reject)
						break
					default:
						reject(new Error(`无对应类型: ${type}`))
						break
				}
			})
		}

		// 登出
		function logout() {
			router.push({ path: '/login' }).then(() => {
				authorizationLogout().finally(() => {
					reset()
					ElMessage.success('退出登录成功.')
				})
			})
		}

		function reset() {
			picture.value = logo
			nickname.value = ''
			routers.value = []
			userinfo.value = undefined
			oauth2Token.value = undefined
			isRouterInitialized.value = false
		}

		return {
			login,
			logout,
			routers,
			picture,
			nickname,
			userinfo,
			setupUser,
			getRouters,
			initRouter,
			oauth2Token,
			isRouterInitialized,
		}
	},
	{
		persistedState: {
			excludePaths: ['routers', 'isRouterInitialized'],
		},
	},
)
